package ranab.gui;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.net.URL;
import java.util.HashMap;

import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;

import ranab.io.IoUtils;

/**
 * This is the GUI utility class.
 * 
 * @author <a href="mailto:rana_b@yahoo.com">Rana Bhattacharyya</a>
 */
public
class GuiUtils {

    private static JFileChooser mDirChoose   = null;    
    private static JFileChooser mFileChoose  = null;
    
    private final static HashMap ICON_CACHE = new HashMap();
    
    /**
     * Create image icon.
     */
    public static ImageIcon createImageIcon(String imgResource) {
        
        synchronized(ICON_CACHE) {
            
            // already cached
            ImageIcon icon = (ImageIcon)ICON_CACHE.get(imgResource);
            if(icon != null) {
                return icon;
            }
            
            // load image
            URL imgUrl = GuiUtils.class.getClassLoader().getResource(imgResource);
            if(imgUrl != null) {
                try {
                    icon = new ImageIcon(imgUrl);
                }
                catch(Exception ex) {
                }
            }
            
            // cache the loaded image
            if(icon != null) {
                ICON_CACHE.put(imgResource, icon);
            }
            
            return icon;
        }
    }


    /**
     * Create splash window. Returns null if image not found.
     */
    public static JWindow createSplashWindow(String imgResource) {

        ImageIcon icon = createImageIcon(imgResource);
        if (icon == null) {
            return null;
        }

        JLabel lab = new JLabel();
        lab.setIcon(icon);

        Dimension iDim = new Dimension(icon.getIconWidth(), icon.getIconHeight());

        JWindow splashWin = new JWindow();
        splashWin.getContentPane().add(lab);
        splashWin.setSize(iDim);
        setLocation(splashWin);
        return splashWin;
    }

    
    /**
     * Get top frame. May return null, if parent frame not found.
     */    
    public static Component getFrame(Component comp) {
        Component frameComp = comp;
        while( (frameComp != null) && !(frameComp instanceof java.awt.Frame) ) {
            frameComp = frameComp.getParent();
        }        
        return frameComp;
    }


    /**
     * Display error message.
     */
    public static void showErrorMessage(Component parent, String str) {
        JOptionPane.showMessageDialog(parent, str, "Error!",
                                      JOptionPane.ERROR_MESSAGE);
    }
    
    
    /**
     * Display exception stack trace
     */
    public static void showErrorMessage(Component parent, Throwable th) {
        String errStr = IoUtils.getStackTrace(th);
        showErrorMessage(parent, errStr);
    }
    

    /**
     * Display warning message.
     */
    public static void showWarningMessage(Component parent, String str) {
        JOptionPane.showMessageDialog(parent, str, "Warning!",
                                      JOptionPane.WARNING_MESSAGE);
    }

    
    /**
     * Display exception stack trace
     */
    public static void showWarningMessage(Component parent, Throwable th) {
        String errStr = IoUtils.getStackTrace(th);
        showWarningMessage(parent, errStr);
    }
    

    /**
     * Display information.
     */
    public static void showInformationMessage(Component parent, String str) {
        JOptionPane.showMessageDialog(parent, str, "Information!",
                                      JOptionPane.INFORMATION_MESSAGE );
    }



    /**
     * Get confirmation.
     */
    public static boolean getConfirmation(Component parent, String str) {

        int res = JOptionPane.showConfirmDialog(parent, 
                                                str,
                                                "Confirmation",
                                                JOptionPane.YES_NO_OPTION, 
                                                JOptionPane.QUESTION_MESSAGE 
                                               );
        return(res == JOptionPane.YES_OPTION); 
    }


    /**
     * Get file name.
     */
    public static String getFileName(Component parent) {

        if (mFileChoose == null) {
            mFileChoose = new JFileChooser();
            mFileChoose.setFileSelectionMode(JFileChooser.FILES_ONLY);
        }

        int returnVal = mFileChoose.showOpenDialog(parent);

        if (returnVal == JFileChooser.APPROVE_OPTION) {
            return mFileChoose.getSelectedFile().getAbsolutePath();
        } else {
            return null;
        }
    }

    /**
     * Get directory name.
     */  
    public static String getDirName(Component parent) {

        if (mDirChoose == null) {
            mDirChoose = new JFileChooser();
            mDirChoose.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        }

        int returnVal = mDirChoose.showOpenDialog(parent);

        if (returnVal == JFileChooser.APPROVE_OPTION) {
            return mDirChoose.getSelectedFile().getAbsolutePath();
        } else {
            return null;
        }
    }

    /**
     * Update component look & feel.
     */
    public static void updateLnF() {

        if (mDirChoose != null) {
            SwingUtilities.updateComponentTreeUI(mDirChoose);
        }
        if (mFileChoose != null) {
            SwingUtilities.updateComponentTreeUI(mFileChoose);
        }
    }

    /**
     * Position properly - center.
     */
    public static void setLocation(Component comp) {
        Dimension cDim = comp.getSize();
        Dimension wDim = Toolkit.getDefaultToolkit().getScreenSize();
        comp.setLocation((wDim.width - cDim.width)/2, (wDim.height - cDim.height)/2);
    }
    
    /**
     * Position with respect to the parent component.
     */
    public static void setLocation(Component comp, Component parent)  {
        Dimension cDim = comp.getSize();
        Rectangle pRect = parent.getBounds();
        int x = pRect.x + (pRect.width - cDim.width)/2;
        int y = pRect.y + (pRect.height - cDim.height)/2;
        comp.setLocation(x, y);
    }
    
    /**
     * Display a new panel. First removes all children, then add.
     */
    public static void showNewPanel(Container parent, Component child) {
        parent.removeAll();
        parent.add(child);
        parent.validate();
        parent.repaint();
    }
     
}
